package model;

import java.util.ArrayList;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;

import util.Read;
import util.Stemmer;

/**
 * The InvIndex class implements the Inverted Index.
 * @author Diogo Kiss and Valerio Lopes
 */
public class InvIndex
{
	TreeMap<String,TreeSet<Item>> indice;
	ArrayList<String> fileList;
	
	/* Constructor */
	public InvIndex()
	{
		this.indice = new TreeMap<String,TreeSet<Item>>();
		this.fileList = new ArrayList<String>();
	}
	
	/**
	 * The getFileList method file returns the ArrayList fileList, which contains all the file names read by the application.
	 * @return The ArrayList with the file names.
	 */
	public ArrayList<String> getFileList()
	{
		return this.fileList;
	}
	
	public TreeMap<String,TreeSet<Item>> getIndice()
	{
		return this.indice;
	}

	/**
	 * The search method simply scans the TreeMap (the inverted index) looking for the word given.
	 * When the method founds, it returns all the files where it exists and the number of occurrences.
	 * @param String word - The word to be found.
	 * @return The list of files that contains the word, as well as the number of occurrences.
	 */
	public String search(String word,boolean stem)
	{
	
		if(stem)
		{
			Stemmer stemmer = new Stemmer();
			word = stemmer.getStemmed(word);
		}
	
		if(!this.indice.containsKey(word))
			return "Nenhuma ocorrencia foi encontrada!";
		else
		{
			System.out.println("Ocorrencia encontrada");

			//Retrieving the array of files which have the word
			TreeSet<Item> files = this.indice.get(word);
			
			StringBuilder dado = new StringBuilder();
			
			for(Item i: files)
			{
				dado.append("\n");
				dado.append(i.getFile());
				dado.append(" - ");
				dado.append(i.getOcorrencias());
			}
			
			return dado.toString();
		}
	}

	
	/**
	 * The addWord method adds the given word into the Inverted Index (implemented by a TreeMap), associating with it the file which it was found and the number of occurrences. 
	 * It treats the cases when the pair word-file already exists in the index, only increasing its occurrence counter.
	 * @param String fileName - The file that is being read by the Read class.
	 * @param String word - The word found in the file.
	 */
	public void addWord(String fileName,String word)
	{	
		Vector<String> stopwords = Read.getStopWords();
		
		if(stopwords.contains(word))
			return;
		
		//adds the file to the ArrayList of files
		if(!fileList.contains(fileName)) fileList.add(fileName);
		
		//Start working with the inverted index
		if(!this.indice.containsKey(word)) //word doesn't exist yet, so create it and set its occurrency counter to 1
		{
			this.indice.put(word,new TreeSet<Item>()); //for each new word, we associate a new TreeSet of Items
			this.indice.get(word).add(new Item(fileName,1));
		}
		
		else //word already exists, so increments its occurrence counter
		{
			TreeSet<Item> it = this.indice.get(word);

			for(Item i: it)
			{
				if(i.getFile().equals(fileName)) //File 'file' is already associated to this word
				{
					i.addOcorrencia();
					return;
				}
			}
			
			it.add(new Item(fileName,1)); //File 'file' is not associated yet to this word
			
		}
		
	}
	
	/**
	 * The contains method scans the Item TreeSet and returns if the given word exists in the given file.
	 * @param String word - The word being searched.
	 * @param String fileName - The name of the file that will be scanned.
	 * @return True if the file contains the word, or else False.
	 */
	public boolean contains(String word,String fileName)
	{
		if(indice.get(word) != null) {
		
			for(Item i: indice.get(word))
			{
				if(i.getFile().equals(fileName))
					return true;
			}
			
			return false;
		}
		else return false;
	}
	

	
}
